
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.PreparedStatement;

/**
 * <p>
 * Esta clase conecta con una base de datos MySql.
 * </p>
 * 
 * <p>
 * Las funciones son la de <code>insertar, borrar, modificar y consultar</code>
 * datos de una base de datos llamada <i>personas</i>
 * </p>
 * 
 * @author Jorge
 */

public class AccessAPI {
	private Connection con;
	private PreparedStatement sentencia;

	/**
	 * Este es el constructor por defecto, cuya funcion es la conexion con la
	 * base de datos.
	 * 
	 * @see #cargarDriver()
	 * @throws ClassNotFoundException
	 *             cuando no puede realizar la conexion con exito.
	 */
	public AccessAPI() throws ClassNotFoundException {
		try {

			cargarDriver();

			this.con = DriverManager.getConnection(
					"jdbc:mysql://localhost/personas", "root", "root");
		} catch (SQLException e) {
			System.out.println("Imposible realizar conexión con la BD");
			e.printStackTrace();
		}
	}

	/**
	 * Carga el driver que permitira la conexion con la base de datos
	 * 
	 * @exception ClassNotFoundException
	 *                cuando no cargue el driver.
	 */
	public void cargarDriver() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}

	/**
	 * Este metodo inserta filas en la base de datos.
	 * 
	 * @param dni
	 *            es el DNI que se insertara en la base de datos.
	 * @param nombre
	 *            es el Nombre que se insertara .
	 * @param edad
	 *            La edad que se inserta en la BD.
	 * @throws DniException
	 *             se lanza cuando el DNI exista en la base de datos.
	 * @throws EdadFormatoException
	 *             salta cuando la edad no este comprendida entre 0 y 200.
	 * @throws NombreFormatoException
	 *             se lanza cuando el nombre no este comprendida entre 1 y 50.
	 */
	public void insertar(int dni, String nombre, int edad) throws DniException,
			EdadFormatoException, NombreFormatoException {
		try {
			if (edad < 0 || edad > 200) {
				throw (new EdadFormatoException());

			} else if (nombre.length() < 1 || nombre.length() > 50) {
				throw (new NombreFormatoException());

			} else {
				try {
					sentencia = (PreparedStatement) con
							.prepareStatement("select dni from personas");
					sentencia.executeQuery();
					ResultSet r = sentencia.getResultSet();

					while (r.next()) {

						int dniBaseDatos = r.getInt("dni");

						if (dni == dniBaseDatos) {

							throw (new DniException());
						}

					}
					sentencia = (PreparedStatement) con
							.prepareStatement("insert into personas values ("
									+ dni + ",'" + nombre + "'," + edad + ")");
					sentencia.execute();

					sentencia.close();
				} catch (DniException e) {
					System.out.println(e.toString());
					System.out.println(e.getMessage());

				} catch (SQLException e1) {

					e1.printStackTrace();
				}

			}
		} catch (NombreFormatoException e) {
			System.out.println(e.toString());
			System.out.println(e.getMessage());
		} catch (EdadFormatoException e) {
			System.out.println(e.toString());
			System.out.println(e.getMessage());
		}
	}

	/**
	 * Borra el usuario cuyo <code>dni</code> sea introducido como parametro 
	 * 
	 * @param dni
	 *            el parametro necesario para el borrado
	 * @throws DniException
	 *             Cuando el dni y el usuario no se encuentran en la BD
	 * @throws SQLException
	 *             para otros errores.
	 */
	public void borrar(int dni) throws DniException {

		try {
			sentencia = (PreparedStatement) con
					.prepareStatement("select dni from personas");
			sentencia.executeQuery();
			ResultSet r = sentencia.getResultSet();
			boolean existe = false;
			while (r.next()) {

				int dniBaseDatos = r.getInt("dni");

				if (dni == dniBaseDatos) {

					sentencia = (PreparedStatement) con
							.prepareStatement("delete from personas where dni="
									+ dni);
					sentencia.execute();
					existe = true;
				}

			}
			if (existe == false) {
				throw (new DniException());
			}
			sentencia.close();
		} catch (DniException e) {
			System.out.println(e.toString());
			System.out.println("El DNI introducido NO existe.");
		} catch (SQLException e1) {

			e1.printStackTrace();
		}

	}

	/**
	 * Actualiza el nombre del usuario, introduciendo como parametro 
	 * un dni (int)  y un nombre (String).
	 * 
	 * @param dni
	 *            parametro necesario para ejecutar el metodo
	 * @param nombre
	 * @throws NombreFormatoException
	 *             Si el nombre no esta comprendido entre 1 y 50 caracteres
	 * @throws DniException
	 *             Si el dni no existe el dni
	 */
	public void modificar(int dni, String nombre)
			throws NombreFormatoException, DniException {
		try {
			if (nombre.length() < 1 || nombre.length() > 50) {

				throw (new NombreFormatoException());
			} else {
				try {
					sentencia = (PreparedStatement) con
							.prepareStatement("select dni from personas");
					sentencia.executeQuery();
					ResultSet r = sentencia.getResultSet();
					boolean existe = false;
					while (r.next()) {

						int dniBaseDatos = r.getInt("dni");

						if (dni == dniBaseDatos) {

							sentencia = (PreparedStatement) con
									.prepareStatement("update personas set nom='"
											+ nombre + "' where dni=" + dni);
							sentencia.execute();
							existe = true;
						}

					}
					if (existe == false) {
						throw (new DniException());
					}
					sentencia.close();
				} catch (DniException e) {
					System.out.println(e.toString());
					System.out.println("El dni introducido NO existe.");
				}

				catch (SQLException e1) {

					e1.printStackTrace();
				}
			}
		} catch (NombreFormatoException n) {
			System.out.println(n.toString());
			System.out.println(n.getMessage());
		}

	}

	/**
	 * Modifica la edad del usuario, introduciendo como parametro 
	 * un dni (int) y una edad (int)
	 * 
	 * @param dni
	 * @param edad
	 * @throws EdadFormatoException
	 *             Si la edad no esta comprendida entre 0 y 200
	 * @throws DniException
	 *             Si el dni introducido no existe
	 */
	public void modificar(int dni, int edad) throws EdadFormatoException,
			DniException {
		try {
			if (edad < 0 || edad > 200) {

				throw (new EdadFormatoException());
			} else {
				try {
					sentencia = (PreparedStatement) con
							.prepareStatement("select dni from personas");
					sentencia.executeQuery();
					ResultSet r = sentencia.getResultSet();
					boolean existe = false;
					while (r.next()) {

						int dniBaseDatos = r.getInt("dni");

						if (dni == dniBaseDatos) {

							sentencia = (PreparedStatement) con
									.prepareStatement("update personas set edad="
											+ edad + " where dni=" + dni);
							sentencia.execute();
							existe = true;
						}

					}
					if (existe == false) {
						throw (new DniException());
					}
					sentencia.close();
				} catch (DniException e) {
					System.out.println(e.toString());
					System.out.println("El DNI introducido NO existe.");
				} catch (SQLException e1) {

					e1.printStackTrace();
				}
			}
		} catch (EdadFormatoException e) {
			System.out.println(e.toString());
			System.out.println(e.getMessage());
		}
	}

	/**
	 * Visualiza el nombre de la persona cuyo dni se introduzca como parametro
	 * 
	 * @param dni
	 * @throws DniException
	 *             si el dni no existe
	 * @throws SQLException
	 *             para cualquier otro error.
	 * @return String que es el nombre que se consulta.
	 */
	public String getNom(int dni) throws DniException {

		String nombre = "";

		try {
			sentencia = (PreparedStatement) con
					.prepareStatement("select dni from personas");
			sentencia.executeQuery();
			ResultSet r = sentencia.getResultSet();
			boolean existe = false;
			while (r.next()) {

				int dniBaseDatos = r.getInt("dni");

				if (dni == dniBaseDatos) {

					sentencia = (PreparedStatement) con
							.prepareStatement("select nom from personas where dni="
									+ dni);
					sentencia.executeQuery();
					ResultSet rs = sentencia.getResultSet();
					while (rs.next()) {

						nombre = rs.getString("nom");

					}
					existe = true;
				}

			}
			if (existe == false) {
				throw (new DniException());
			}
			sentencia.close();
		} catch (SQLException e1) {

			e1.printStackTrace();
		}
		return nombre;
	}

	/**
	 * Devuelve un <code>int</code> cuyo valor es la edad que se quiere
	 * consultar introduciendo un dni como parametro.
	 * 
	 * @param dni
	 *            dato de tipo <code>int</code>
	 * @return  edad a consultar
	 * @throws DniException
	 *             cuando el dni no existe
	 */
	public int getEdad(int dni) throws DniException {

		int edad = 0;
		try {
			sentencia = (PreparedStatement) con
					.prepareStatement("select dni from personas");
			sentencia.executeQuery();
			ResultSet r = sentencia.getResultSet();
			boolean existe = false;
			while (r.next()) {

				int dniBaseDatos = r.getInt("dni");

				if (dni == dniBaseDatos) {

					sentencia = (PreparedStatement) con
							.prepareStatement("select edad from personas where dni="
									+ dni);
					sentencia.executeQuery();
					ResultSet rs = sentencia.getResultSet();
					while (rs.next()) {

						edad = rs.getInt("edad");

					}
					existe = true;
				}

			}
			if (existe == false) {
				throw (new DniException());
			}
			sentencia.close();
		} catch (SQLException e1) {

			e1.printStackTrace();
		}
		return edad;
	}

	/**
	 * Cierra la conexion con la base de datos
	 * 
	 * @throws Throwable
	 */
	protected void finalize() throws Throwable {
		try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}






